package filter;

import java.io.ByteArrayInputStream;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import log.ServerLogger;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import util.NumberUtil;
import util.ServerCache;
import xml.RequestBody;
import xml.ResponseBody;
import core.Global;
import core.MinaSocket;


public class ClientTextDecoder extends CumulativeProtocolDecoder
{
	private IoBuffer buff = IoBuffer.allocate(2048).setAutoExpand(true);
/*
	protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
		
		
		boolean complete = false;
		while (in.hasRemaining()) {
			byte b = in.get();

			// CIMConstant.MESSAGE_SEPARATE 为消息界限
			// 当一次收到多个消息时，以此分隔解析多个消息
			
			if (b == '\b') {
				complete = true;
				break;
			} else {
				buff.put(b);
			}
		}
		if (complete) {
			buff.flip();
			byte[] bytes = new byte[buff.limit()];
			buff.get(bytes);
			String message = new String(bytes, "UTF-8");
			buff.clear();
			if((message.startsWith("<?xml version=\"1.0\"")))
			{
				//ServerLogger.Error("上位机发送协议:"+message);
				Object msgObject = mappingMessageObject(message);
				out.write(msgObject);
			}else
			{
				
				ServerLogger.Error("上位机发送协议不标准:"+message);
				return false;
			}
			
		}
		return true;

	}
	*/
	@Override
	protected boolean doDecode(IoSession iosession, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
		
		if(in.remaining() > 0){//有数据时，读取4字节判断消息长度  
            byte [] sizeBytes = new byte[12];  
            in.mark();//标记当前位置，以便reset  
            in.get(sizeBytes);//读取前4字节  
                        //NumberUtil是自己写的一个int转byte[]的一个工具类  
            String xmllenStr = new String(sizeBytes,"UTF-8"); 
            //int size = NumberUtil.bytes2int(sizeBytes);  
            int size = Integer.parseInt(xmllenStr.trim());
            //如果消息内容的长度不够则直接返回true  
            if(size > in.remaining()){//如果消息内容不够，则重置，相当于不读取size  
                in.reset();  
                return false;//接收新数据，以拼凑成完整数据  
            } else{  
                byte[] bytes = new byte[size];   
                in.get(bytes, 0, size);  
                String xmlStr = new String(bytes,"UTF-8");  
                //System.out.println("------------"+xmlStr);  
                if(null != xmlStr && xmlStr.length() > 0){  
                	if((xmlStr.startsWith("<?xml version=\"1.0\"")))
        			{
                		//xmlStr = xmlStr.substring(0, xmlStr.length()-1);//这个以后可能改
        				Object msgObject = mappingMessageObject(xmlStr);
        				out.write(msgObject);
        			}else
        			{
        				ServerLogger.Error("客户端发送协议不标准:"+xmlStr);

        			}
                }  
                if(in.remaining() > 0){//如果读取内容后还粘了包，就让父类再给俺  一次，进行下一次解析  
                    return true;  
                }  
            }  
        }  
        return false;//处理成功，让父类进行接收下个包
	}
	
	
	public void dispose(IoSession arg0) throws Exception
	{

	}

	public void finishDecode(IoSession arg0, ProtocolDecoderOutput arg1)
			throws Exception
	{

	}
	private Object mappingMessageObject(String  message) throws Exception {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
		DocumentBuilder builder = factory.newDocumentBuilder();  
		Document doc = (Document) builder.parse(new ByteArrayInputStream(message.toString().getBytes("UTF-8")));

		String name = doc.getDocumentElement().getTagName();
		/*
		if (name.equals("reply")) {
			RequestBody reply = new RequestBody();
			reply.setKey(doc.getElementsByTagName("key").item(0).getTextContent());
			reply.setCode(doc.getElementsByTagName("code").item(0).getTextContent());
			NodeList items = doc.getElementsByTagName("data").item(0).getChildNodes();  
			for (int i = 0; i < items.getLength(); i++) {  
				Node node = items.item(i);  
				reply.getData().put(node.getNodeName(), node.getTextContent());
			}  
			return reply;
		}
	    */
		if (name.equals("request")) {

			RequestBody body = new RequestBody();
			body.setType(doc.getElementsByTagName("type").item(0).getTextContent());
			body.setSender(doc.getElementsByTagName("sender").item(0).getTextContent());
			body.setReciever(doc.getElementsByTagName("reciever").item(0).getTextContent());
			NodeList items = doc.getElementsByTagName("data").item(0).getChildNodes();  
			for (int i = 0; i < items.getLength(); i++) {  
				Node node = items.item(i);  
				body.getData().put(node.getNodeName(), node.getTextContent());
			}
			body.setTimestamp(Long.valueOf(doc.getElementsByTagName("timestamp").item(0).getTextContent()));
			return body;
		}else if (name.equals("response")) {

			ResponseBody body = new ResponseBody();
			body.setType(doc.getElementsByTagName("type").item(0).getTextContent());
			body.setSender(doc.getElementsByTagName("sender").item(0).getTextContent());
			body.setReciever(doc.getElementsByTagName("reciever").item(0).getTextContent());
			NodeList items = doc.getElementsByTagName("data").item(0).getChildNodes();  
			for (int i = 0; i < items.getLength(); i++) {  
				Node node = items.item(i);  
				body.getData().put(node.getNodeName(), node.getTextContent());
			}
			body.setTimestamp(Long.valueOf(doc.getElementsByTagName("timestamp").item(0).getTextContent()));
			return body;
		}else {
			ServerLogger.Error("getTagName错误");
		}

		return null;
	}

}
